#include "Helper.h"
#include <stdlib.h>
#include <time.h>
#include <math.h>

using namespace NeuralPlusPlus::Core;

void NeuralPlusPlus::Core::Helper::ValidateNotNull( void *value, string name )
	{
	if (value == NULL)
		{
		throw ("The argument should not be null : " + name);
		}
	}

void NeuralPlusPlus::Core::Helper::ValidateNotNegative( double value, string name )
	{
	if (value < 0)
		{
		throw ("The argument should be non-negative" + name);
		}
	}

void NeuralPlusPlus::Core::Helper::ValidatePositive( double value, string name )
	{
	if (value <= 0)
		{
		throw ("The argument should be non-zero positive" + name);
		}
	}

void NeuralPlusPlus::Core::Helper::ValidateWithinRange( double value, double min, double max, string name )
	{
	if (value < min || value > max)
		{
		throw ("The argument is out of range : " + name);
		}
	}

double NeuralPlusPlus::Core::Helper::GetRandom()
	{
	return (double)rand()/(double)RAND_MAX;
	}

double NeuralPlusPlus::Core::Helper::GetRandom( double min, double max )
	{
	if (min > max)
		{
		return GetRandom(max, min);
		}
	return (min + (max - min) * ((double)rand()/(double)RAND_MAX));
	}

int* NeuralPlusPlus::Core::Helper::GetRandomOrder( int size )
	{
	int *randomOrder = new int[size];

	for (int i = 0; i < size; i++)
		{
		randomOrder[i] = i;
		}

	for (int i = 0; i < size; i++)
		{
		int randomPosition = (rand()%size);
		int temp = randomOrder[i];
		randomOrder[i] = randomOrder[randomPosition];
		randomOrder[randomPosition] = temp;
		}
	return randomOrder;
	}

double* NeuralPlusPlus::Core::Helper::Normalize( double* vector, int vectorLength, double magnitude /*= 1*/)
	{
	double factor = 0.0;
	for (int i = 0; i < vectorLength; i++)
		{
		factor += vector[i] * vector[i];
		}

	double *normalizedVector = new double[vectorLength];
	if (factor != 0)
		{
		factor = sqrt(magnitude / factor);
		for (int i = 0; i < vectorLength; i++)
			{
			normalizedVector[i] = vector[i] * factor;
			}
		}
	return normalizedVector;
	}

double* NeuralPlusPlus::Core::Helper::GetRandomVector( int count, double magnitude )
	{
	double *result = new double[count];
	for (int i = 0; i < count; i++)
		{
		result[i] = Helper::GetRandom();
		}
	double *normalizedVector = Normalize(result, count, magnitude);
	delete[] result;
	return normalizedVector;
	}

void NeuralPlusPlus::Core::Helper::SeedRandom()
	{
	srand((unsigned)time(NULL));
	}